home *** CD-ROM | disk | FTP | other *** search
- /* GRAPHIC LISP */
- /* Scritto nel 1991-94 da Zoia Andrea Michele */
- /* Via Pergola #1 Tirano (SO) Tel. 0342-704210 */
- /* file clos_lf2.c */
-
- #include "clos.h"
-
- /* LF_PARAMS --> (node nin,node_p *nout,node genv,node lenv,unsigned fl ) */
- /* convenzioni per le sintassi:
- Metasimboli: { } * + |
- { } Raggruppamento
- * Zero o piu' occorrenze
- + Una o piu' occorrenze
- | OR o l'occorrenza di destra o quella di sinistra
-
- es:
- ( { a | b }+ ) corrisponde a tutte le stringhe del tipo
- ( a a b b a b .... )
- ma non alla stringa ( )
- */
-
-
- /* funzioni di sistema e di debug ***********************************/
- /* GC , EXIT , STACKTRACE , TRACE , UNTRACE */
- /* GETTIME , OBLIST , GET_GENV , GET_LENV , HASHSTAT */
- /* BREAK , CONTINUE , DRIBBLE */
- /********************************************************************/
-
- /* funzioni varie (da ricontrollare !!!)*****************************/
- /* FUNCALL , APPLY RICONTROLLARE, MAPCAR , PUSH , POP , ASSOC */
- /********************************************************************/
-
- /* mettere la funzione TYPE che ritorna il tipo di un nodo */
-
- void lf_gc LF_PARAMS
- {
- extern hash_t MaxHash;
- extern hash_t HashAllocated;
-
- extern lsiz_t maxname;
- extern lsiz_t nameidx;
-
- lsiz_t alloc_counter;
- lsiz_t free_counter;
-
- if(nin!=NIL){
- sprintf(buf1," Graphic CLOS V%s By Zoia Andrea \n",CLOS_VERSION);
- lisp_print_string(buf1,stdout);
- }
-
- node_gc();
- string_gc();
- node_count(&alloc_counter,&free_counter);
-
-
- sprintf(buf1,"Total Nodes %7lu Allocated %7lu Free %7lu\n",
- alloc_counter+free_counter,alloc_counter,free_counter);
- lisp_print_string(buf1,stderr);
-
- sprintf(buf1,"Total Strings %7lu Allocated %7lu Free %7lu\n",
- maxname,nameidx,maxname-nameidx);
- lisp_print_string(buf1,stderr);
-
- sprintf(buf1,"Total Hash Entries %7lu Allocated %7lu Free %7lu\n",
- MaxHash,HashAllocated,MaxHash-HashAllocated);
- lisp_print_string(buf1,stderr);
-
- nout->type=P_ALLNODE;
- nout->node=T;
- }
-
- void lf_exit LF_PARAMS
- {
- if(nin!=NIL)
- error(E_TOOMANYARGS,ERR_TBLVL|ERR_MERROR|ERR_PNODE,&NIL);
- if(dribble_file)fclose(dribble_file);
- lisp_free();
- clos_non_ansi_exit();
- }
-
-
-
-
- void lf_stacktrace LF_PARAMS
- {
- extern int StackTrace;
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- if(calc_pointer(nout)!=NIL)
- StackTrace=TRUE;
- else
- StackTrace=FALSE;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
-
- void lf_trace LF_PARAMS
- {
- /* (TRACE function-name) */
- /* accende il flag trace ritorna t se lo ha acceso , nil se era gia' acceso */
-
- if(IS_CONS(nin)){
- if(IS_NAME(CONSLEFT(nin))){
- if(HAS_FUNCTION(CONSLEFT(nin))){
- if(IS_TRACE(FUNCTION(CONSLEFT(nin)))){
- nout->node=NIL;
- }else{
- nout->node=T;
- TRACE(FUNCTION(CONSLEFT(nin)));
- }
- nout->type=P_ALLNODE;
- return;
- }
- nin=CONSLEFT(nin);
- error(E_UNBOUNDFUNC,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- nin=CONSLEFT(nin);
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_untrace LF_PARAMS
- {
- /* (UNTRACE function-name) */
- /* spegne il flag trace ritorna t se lo ha spento, nil se era gia' spento */
-
- if(IS_CONS(nin)){
- if(IS_NAME(CONSLEFT(nin))){
- if(HAS_FUNCTION(CONSLEFT(nin))){
- if(IS_TRACE(FUNCTION(CONSLEFT(nin)))){
- nout->node=T;
- UNTRACE(FUNCTION(CONSLEFT(nin)));
- }else{
- nout->node=NIL;
- }
- nout->type=P_ALLNODE;
- return;
- }
- nin=CONSLEFT(nin);
- error(E_UNBOUNDFUNC,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- nin=CONSLEFT(nin);
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- void lf_gettime LF_PARAMS
- {
- if(nin==NIL){
- TYPE(nout->node=node_make())|=NT_IS_VALUE+NT_INTEGER;
- INTEGER(nout->node)=na_millitime();
- nout->type=P_ALLNODE;
- return;
- }
- error(nin==NIL?E_FEWARGS:E_BADLIST,
- ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
- void lf_oblist LF_PARAMS
- {
- if(nin==NIL){
- nout->node=node_scan();
- nout->type=P_ALLNODE;
- return;
- }
- error(nin==NIL?E_FEWARGS:E_BADLIST,
- ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_fixlist LF_PARAMS
- {
- if(nin==NIL){
- nout->node=node_scan_fix();
- nout->type=P_ALLNODE;
- return;
- }
- error(nin==NIL?E_FEWARGS:E_BADLIST,
- ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
-
-
- void lf_getlenv LF_PARAMS
- {
- if(nin==NIL){
- nout->type=P_ALLNODE;
- nout->node=lenv;
- return;
- }
- error(E_TOOMANYARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
- void lf_getgenv LF_PARAMS
- {
- if(nin==NIL){
- nout->type=P_ALLNODE;
- nout->node=genv;
- return;
- }
- error(E_TOOMANYARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_hashstat LF_PARAMS
- {
- if(nin!=NIL)
- error(E_TOOMANYARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- hash_stat();
- nout->type=P_ALLNODE;
- nout->node=T;
- }
-
-
- void lf_break LF_PARAMS
- {
- if(nin==NIL){
- lisp_main_loop(genv,lenv,node_getlastlock());
- nout->type=P_ALLNODE;
- nout->node=T;
- return;
- }
- error(E_TOOMANYARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_continue LF_PARAMS
- {
- longjmp(break_jmp,LONGJMP_CONTINUE);
- }
-
- void lf_dribble LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- nin=calc_pointer(nout);
- nout->type=P_ALLNODE;
- if(nin==NIL){
- if(dribble_file){
- fclose(dribble_file);
- dribble_file=NULL;
- nout->node=T;
- }else{
- nout->node=NIL;
- }
- return;
- }
-
- if(IS_VALUE(nin) && GET_VTYPE(nin)==NT_STRING){
- if(dribble_file){
- nout->node=NIL;
- return;
- }
- string_get(STRING(nin),buf1);
- dribble_file=fopen(buf1,"w+t");
- if(dribble_file){
- nout->node=T;
- }else{
- nout->node=NIL;
- }
- return;
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
-
-
- /**************************** Funzioni varie ***************************/
-
- /* sintassi (funcall funzione {parametri}* ) */
- /* chiama la funzione passandole i parametri */
- void lf_funcall LF_PARAMS
- {
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- apply_func(calc_pointer(nout),CONSRIGHT(nin),nout,genv,lenv,fl);
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- /* syntax (apply func sx* ) */
- /* se e(sx) e' una lista la si copia */
- /* se e(sx) non e' una lista si appende l'elemento alla lista gia' esistente*/
- void lf_apply LF_PARAMS
- {
- node list,func,n1,n2,prev=NIL,first,last;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- func=calc_pointer(nout);
- n1=list=eval_list(CONSRIGHT(nin),genv,lenv);
- while(IS_CONS(n1)){
- n2=CONSLEFT(n1);
- if(IS_CONS(n2)){
- first=n2;
- while(IS_CONS(n2)){
- last=n2;
- n2=CONSRIGHT(n2);
- }
- if(prev==NIL){
- list=first;
- }else{
- CONSRIGHT(prev)=first;
- }
- CONSRIGHT(last)=CONSRIGHT(n1);
- n1=last;
- }
- prev=n1;
- n1=CONSRIGHT(n1);
- }
- apply_func(func,list,nout,genv,lenv,fl);
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- /* sintassi (mapcar funzione {arglist}*) */
- void lf_mapcar LF_PARAMS
- {
- node func;
- node parl=node_make();
- node rlist=NIL;
- node last_rnode=nin;
- node p,q,z;
- node quote=node_alloc("QUOTE");
-
- TYPE(parl)|=NT_IS_CONS;
- CONSLEFT(parl)=CONSRIGHT(parl)=NIL;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_SETF);
- func=calc_pointer(nout);
- while(IS_CONS(nin=CONSRIGHT(nin))){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_SETF);
- p=parl;
- rlist=calc_pointer(nout);
- /* rlist = (s1 s2 .. sn) */
- while(IS_CONS(rlist)){
- if(CONSLEFT(p)==NIL){
- TYPE(q=CONSLEFT(p)=node_make())|=NT_IS_CONS;
- TYPE(z=node_make())|=NT_IS_CONS;
- CONSLEFT(z)=quote;
- TYPE(CONSRIGHT(z)=node_make())|=NT_IS_CONS;
- CONSLEFT(CONSRIGHT(z))=CONSLEFT(rlist);
- CONSRIGHT(CONSRIGHT(z))=NIL;
- CONSLEFT(q)=z;
- CONSRIGHT(q)=NIL;
- }else{
- q=CONSLEFT(p);
- while(CONSRIGHT(q)!=NIL) q=CONSRIGHT(q);
- TYPE(CONSRIGHT(q)=node_make())|=NT_IS_CONS;
- TYPE(z=node_make())|=NT_IS_CONS;
- CONSLEFT(z)=quote;
- TYPE(CONSRIGHT(z)=node_make())|=NT_IS_CONS;
- CONSLEFT(CONSRIGHT(z))=CONSLEFT(rlist);
- CONSRIGHT(CONSRIGHT(z))=NIL;
- CONSLEFT(CONSRIGHT(q))=z;
- CONSRIGHT(CONSRIGHT(q))=NIL;
- }
- if(CONSRIGHT(p)==NIL){
- TYPE(CONSRIGHT(p)=node_make())|=NT_IS_CONS;
- CONSLEFT(CONSRIGHT(p))=CONSRIGHT(CONSRIGHT(p))=NIL;
- }
- p=CONSRIGHT(p);
- rlist=CONSRIGHT(rlist);
- }
- }
- /* parl= ( ('s11 's12 .. 's1n) ('s21 's22 .. 's2n )...('sm1 'sm2 .. 'smn) () )*/
- while(CONSLEFT(parl)!=NIL){
- apply_func(func,CONSLEFT(parl),nout,genv,lenv,EVAL_NORM);
- if(rlist==NIL){
- TYPE(rlist=last_rnode=node_make())|=NT_IS_CONS;
- }else{
- TYPE(CONSRIGHT(last_rnode)=node_make())|=NT_IS_CONS;
- last_rnode=CONSRIGHT(last_rnode);
- }
- CONSLEFT(last_rnode)=calc_pointer(nout);
- CONSRIGHT(last_rnode)=NIL;
- parl=CONSRIGHT(parl);
- }
- nout->node=rlist;
- nout->type=P_ALLNODE;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
- void lf_push LF_PARAMS
- {
- /* SINTASSI (push valore lista) */
- node n,value;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- value=calc_pointer(nout);
- if(IS_CONS(CONSRIGHT(nin))){
- eval(CONSLEFT(CONSRIGHT(nin)),nout,genv,lenv,EVAL_NORM);
- TYPE(n=node_make())|=NT_IS_CONS;
- CONSLEFT(n)=value;
- switch(nout->type){
- case P_VALUE:
- CONSRIGHT(n)=VALUE(nout->node);
- VALUE(nout->node)=n;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- case P_PLIST:
- CONSRIGHT(n)=PLIST(nout->node);
- PLIST(nout->node)=n;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- case P_FUNC:
- CONSRIGHT(n)=FUNCTION(nout->node);
- FUNCTION(nout->node)=n;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- case P_CLASS:
- error(E_BADARGS,ERR_MINTERNAL|ERR_TBLVL|ERR_PNODE,&nin);
- break;
- case P_ALLNODE:
- CONSRIGHT(n)=nout->node;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- case P_CONSLEFT:
- CONSRIGHT(n)=CONSLEFT(nout->node);
- CONSLEFT(nout->node)=n;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
- case P_CONSRIGHT:
- CONSRIGHT(n)=CONSRIGHT(nout->node);
- CONSRIGHT(nout->node)=n;
- nout->node=n;
- nout->type=P_ALLNODE;
- return;
-
- }
- nin=calc_pointer(nout);
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_pop LF_PARAMS
- {
- /* sintassi (POP lista) */
- node n;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_NORM);
- switch(nout->type){
- case P_VALUE:
- if(IS_CONS(n=VALUE(nout->node))){
- VALUE(nout->node)=CONSRIGHT(n);
- nout->node=CONSLEFT(n);
- nout->type=P_ALLNODE;
- return;
- }
- break;
- case P_PLIST:
- if(IS_CONS(n=PLIST(nout->node))){
- PLIST(nout->node)=CONSRIGHT(n);
- nout->node=CONSLEFT(n);
- nout->type=P_ALLNODE;
- return;
- }
- case P_FUNC:
- if(IS_CONS(n=FUNCTION(nout->node))){
- FUNCTION(nout->node)=CONSRIGHT(n);
- nout->node=CONSLEFT(n);
- nout->type=P_ALLNODE;
- return;
- }
- case P_CLASS:
- error(E_BADARGS,ERR_MINTERNAL|ERR_TBLVL|ERR_PNODE,&nin);
- break;
- case P_ALLNODE:
- if(IS_CONS(nout->node)){
- nout->node=CONSLEFT(nout->node);
- return;
- }
- break;
- case P_CONSLEFT:
- if(IS_CONS(n=CONSLEFT(nout->node))){
- CONSLEFT(nout->node)=CONSRIGHT(n);
- nout->node=CONSLEFT(n);
- nout->type=P_ALLNODE;
- return;
- }
- break;
- case P_CONSRIGHT:
- if(IS_CONS(n=CONSRIGHT(nout->node))){
- CONSRIGHT(nout->node)=CONSRIGHT(n);
- nout->node=CONSLEFT(n);
- nout->type=P_ALLNODE;
- return;
- }
- break;
- }
- nin=calc_pointer(nout);
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
- void lf_assoc LF_PARAMS
- {
- /* (ASSOC <chiave> <a-list> {:TEST <funzione>}? ) */
- /* a-list puo' essere una lista di cons o una lista di liste */
- /* es: ( (a 1) (b 2) ) oppure ( (a . 1) (b . 2) ) */
- /* chiave deve essere un nome */
-
- node key;
- node alist;
- node test=node_alloc("TEST");
- node quote=node_alloc("QUOTE");
- node n;
- node ni;
- node testfunc=NIL;
-
- if(IS_CONS(nin)){
- key=CONSLEFT(nin);
- if(IS_CONS(CONSRIGHT(nin))){
- eval(CONSLEFT(CONSRIGHT(nin)),nout,genv,lenv,EVAL_NORM);
- alist=calc_pointer(nout);
-
- if(IS_CONS(ni=CONSRIGHT(CONSRIGHT(nin)))){
- n=CONSLEFT(ni);
- if(IS_VALUE(n)&&GET_VTYPE(n)==NT_CNAME&&CNAME(n)==test){
- if(IS_CONS(ni=CONSRIGHT(ni))){
- eval(CONSLEFT(ni),nout,genv,lenv,EVAL_NORM);
-
- /* costruisce una lista */
- /* (key 'CONSLEFT(CONSLEFT(alist)) ) */
- /* da passare alla funzione di test */
-
- TYPE(n=node_make())|=NT_IS_CONS;
- CONSLEFT(n)=NIL; /* qui' vanno i vari CONSLEFT(CONSLEFT(alist)) */
- CONSRIGHT(n)=NIL;
- testfunc=n; /* n=( nil ) */
-
- TYPE(ni=node_make())|=NT_IS_CONS;
- CONSLEFT(ni)=quote;
- CONSRIGHT(ni)=n; /* ni= (quote nil) */
-
- TYPE(n=node_make())|=NT_IS_CONS;
- CONSLEFT(n)=ni;
- CONSRIGHT(n)=NIL; /* n=((quote nil)) */
-
- TYPE(ni=node_make())|=NT_IS_CONS;
- CONSLEFT(ni)=key;
- CONSRIGHT(ni)=n; /* ni=(key (quote nil)) */
-
- n=testfunc;
- testfunc=calc_pointer(nout);
-
- while(IS_CONS(alist)){
- if(IS_CONS(CONSLEFT(alist))){
- CONSLEFT(n)=CONSLEFT(CONSLEFT(alist));
- /* ni=(key (quote (car(car alist)))) */
- apply_func(testfunc,ni,nout,genv,lenv,EVAL_NORM);
- if(calc_pointer(nout)!=NIL){
- nout->node=alist;
- nout->type=P_CONSLEFT;
- return;
- }
- }
- alist=CONSRIGHT(alist);
- }
- nout->node=NIL;
- nout->type=P_ALLNODE;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&n);
- }else{
- eval(key,nout,genv,lenv,EVAL_NORM);
- key=calc_pointer(nout);
- if( ! (IS_NAME(key)&&HAS_NAME(key)))
- error(E_BADARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&key);
- while(IS_CONS(alist)){
- if(IS_CONS(CONSLEFT(alist))){
- if(key==CONSLEFT(CONSLEFT(alist))){
- nout->node=alist;
- nout->type=P_CONSLEFT;
- return;
- }
- }
- alist=CONSRIGHT(alist);
- }
- }
- nout->node=NIL;
- nout->type=P_ALLNODE;
- return;
- }
- }
- error(E_FEWARGS,ERR_MERROR|ERR_TBLVL|ERR_PNODE,&nin);
- }
-
-
-
-
-